package com.linkallcloud.web.processor;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.linkallcloud.core.exception.BaseException;
import com.linkallcloud.core.exception.BizException;
import com.linkallcloud.core.face.message.FaceMessage;
import com.linkallcloud.core.face.message.request.FaceRequest;
import com.linkallcloud.core.face.message.request.LoginFaceRequest;
import com.linkallcloud.core.lang.Strings;
import com.linkallcloud.core.www.ISessionBUser;
import com.linkallcloud.core.www.ISessionCUser;
import com.linkallcloud.core.www.ISimpleUser;
import com.linkallcloud.web.face.annotation.Face;
import com.linkallcloud.web.utils.Controllers;

public abstract class LoginRequestProcessor extends FaceRequestProcessor {

    @Override
    protected ISimpleUser doCheckLogin(FaceMessage request, Method method) throws Exception {
        Face faceAnno = method.getAnnotation(Face.class);
        if (faceAnno != null && faceAnno.login()) {// 需要登录校验
            if (request instanceof FaceRequest) {
                FaceRequest req = (FaceRequest) request;
                HttpServletRequest hsr =
                        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                ISimpleUser suser = getSessionUserByFaceRequest(req, hsr);
                if (suser == null) {
                    throw new BaseException("e.face.login", "此方法需要登录校验，所以请求参数必须包含令牌信息。");
                } else {
                    if (request instanceof LoginFaceRequest) {
                        LoginFaceRequest lreq = (LoginFaceRequest) request;
                        if (suser.getClass().isAssignableFrom(ISessionCUser.class)) {
                            ISessionCUser csu = (ISessionCUser) suser;
                            lreq.setUser(csu.getSid());
                        } else if (suser.getClass().isAssignableFrom(ISessionBUser.class)) {
                            ISessionBUser bsu = (ISessionBUser) suser;
                            lreq.setUser(bsu.getSid());
                            lreq.setCompany(bsu.getCompany());
                        }
                    }
                }
                return suser;
            } else {
                throw new BaseException("e.face.login", "此方法需要登录校验，所以请求参数必须包含令牌信息。");
            }
        }
        return null;
    }

    /**
     * @param fr
     * @param hsr
     * @return
     * @throws BizException
     */
    protected ISimpleUser getSessionUserByFaceRequest(FaceRequest fr, HttpServletRequest hsr) throws BizException {
        if (Strings.isBlank(fr.getAppCode())) {
            throw new BizException("e.face.login", "appCode参数错误");
        }
        String token = Controllers.getLacToken(fr, hsr);
        if (!Strings.isBlank(token)) {
            fr.setToken(token);
            return getSessionUserByToken(token, fr);
        }
        throw new BizException("e.face.login", "token参数错误");
    }

    /**
     * 根据token加载用户SessionUser
     *
     * @param token
     * @return
     * @throws BizException
     */
    protected abstract ISimpleUser getSessionUserByToken(String token, FaceRequest fr) throws BizException;

}
